﻿//-----------------------------------------------------------------------
// <copyright file="Track.cs" company="iTunesEncodeNet">
//  (c) 2009 Vlasenko Dmitry
// </copyright>
//-----------------------------------------------------------------------

namespace ITunesEncodeNet
{
    using System.IO;

    /// <summary>
    /// Represents ITunesEncodeNet track.
    /// </summary>
    internal class Track
    {
        /// <summary>
        /// Track artist.
        /// </summary>
        private string artist;

        /// <summary>
        /// Track name.
        /// </summary>
        private string name;

        /// <summary>
        /// Album title.
        /// </summary>
        private string album;

        /// <summary>
        /// Track number.
        /// </summary>
        private uint? trackNumber;

        /// <summary>
        /// Publication year.
        /// </summary>
        private uint? year;

        /// <summary>
        /// Track genre.
        /// </summary>
        private string genre;

        /// <summary>
        /// Track comment.
        /// </summary>
        private string comment;

        /// <summary>
        /// Initial *.flac or *.ape file.
        /// </summary>
        private FileInfo initialFile;

        /// <summary>
        /// Intermediate *.wav file.
        /// </summary>
        private FileInfo intermediateFile;

        /// <summary>
        /// Result *.m4a file.
        /// </summary>
        private FileInfo resultFile;

        /// <summary>
        /// Initializes a new instance of the Track class.
        /// </summary>
        /// <param name="fileName">Full path to initial *.flac or *.ape file.</param>
        public Track(string fileName)
        {
            this.initialFile = new FileInfo(fileName);
            Tagger tagger = null;

            switch (this.initialFile.Extension)
            {
                case ".flac":
                    tagger = new Tagger(EncoderOptions.EncoderType.flac);
                    break;

                case ".ape":
                    tagger = new Tagger(EncoderOptions.EncoderType.ape);
                    break;
            }

            this.artist = tagger.GetArtist(this.initialFile.FullName);
            this.name = tagger.GetName(this.initialFile.FullName);
            this.album = tagger.GetAlbum(this.initialFile.FullName);
            this.trackNumber = tagger.GetTrackNumber(this.initialFile.FullName);
            this.year = tagger.GetYear(this.initialFile.FullName);
            this.genre = tagger.GetGenre(this.initialFile.FullName);
            this.comment = tagger.GetComment(this.initialFile.FullName);
        }

        /// <summary>
        /// Gets full name of initial *.flac or *.ape file.
        /// </summary>
        public string FileName
        {
            get { return this.initialFile.Name; }
        }

        /// <summary>
        /// Decodes initial *.flac or *.ape file into intermediate *.wav file.
        /// </summary>
        /// <param name="destinationDirName">Full path to destination directory.</param>
        /// <returns>True if decoding finished successfully, otherwise false.</returns>
        public bool Decode(string destinationDirName)
        {
            Decoder decoder = null;

            switch (this.initialFile.Extension)
            {
                case ".flac":
                    decoder = new Decoder(EncoderOptions.EncoderType.flac);
                    break;

                case ".ape":
                    decoder = new Decoder(EncoderOptions.EncoderType.ape);
                    break;
            }

            string temp = decoder.Decode(this.initialFile.FullName, destinationDirName);

            if (string.IsNullOrEmpty(temp))
            {
                return false;
            }

            this.intermediateFile = new FileInfo(temp);

            return true;
        }

        /// <summary>
        /// Encodes intermediate *.wav file into *.m4a file.
        /// </summary>
        /// <returns>True if encoding finished successfully, otherwise false.</returns>
        public bool Encode()
        {
            Encoder encoder = new Encoder();

            string temp = encoder.Encode(this.intermediateFile.FullName, this.artist, this.name, this.album, this.trackNumber, this.year, this.genre, this.comment);

            if (string.IsNullOrEmpty(temp))
            {
                return false;
            }

            this.resultFile = new FileInfo(temp);

            return true;
        }

        /// <summary>
        /// Moves result file.
        /// </summary>
        /// <param name="destinationDirName">Full path to destination directory.</param>
        public void Move(string destinationDirName)
        {
            string temp = Path.Combine(destinationDirName, this.initialFile.Directory.Name);

            DirectoryInfo destinationDir = new DirectoryInfo(temp);
            destinationDir.Create();

            string extension = this.initialFile.Extension;
            string destinationFileName = Path.Combine(temp, this.initialFile.Name.Replace(extension, ".m4a"));

            this.resultFile.CopyTo(destinationFileName);

            this.intermediateFile.Delete();
            this.resultFile.Delete();
        }
    }
}
